#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <openssl/rsa.h> 
#include <openssl/pem.h> 
#include <openssl/err.h> 
#include <iostream> 
#include <string> 
#include "Base64.h" 
 
std::string RsaEncrypt(const std::string& str, const std::string& path) 
{
    RSA *rsa = NULL; 
    FILE *file = NULL; 
    char *ciphertext = NULL; 
    int len = 0; 
    int ret = 0; 
  
    file = fopen(path.c_str(), "r"); 
    if (file == NULL) { 
        return std::string(); 
    } 
  
    //*注解1
    //rsa = PEM_read_RSAPublicKey(file, NULL, NULL, NULL); 
    rsa = PEM_read_RSA_PUBKEY(file, NULL, NULL, NULL); 
    if (rsa == NULL) { 
        ERR_print_errors_fp(stdout); 
        fclose(file); 
        return std::string(); 
    }
  
    len = RSA_size(rsa); 
    ciphertext = (char *)malloc(len + 1); 
    if (ciphertext == NULL) { 
        RSA_free(rsa); 
        fclose(file); 
        return std::string(); 
    }
    memset(ciphertext, 0, len + 1); 
  
　　 //*注解2
    ret = RSA_public_encrypt(str.length(), (unsigned char *)str.c_str(), (unsigned char*)ciphertext, rsa, RSA_PKCS1_PADDING); 
    if (ret < 0) { 
        ERR_print_errors_fp(stdout); 
        free(ciphertext); 
        RSA_free(rsa); 
        fclose(file); 
        return std::string(); 
    } 
 
    //*注解3
    //std::string s(ciphertext);    //不能使用这个构造函数，有的密文使用这个构造函数构造出的string会缺失部分数据，导致无法解密 
    std::string s(ciphertext, ret); 
  
    free(ciphertext); 
    RSA_free(rsa); 
    fclose(file); 
  
    return s; 
} 
 
std::string RsaDecrypt(const std::string& str, const std::string& path)  
{ 
    RSA *rsa = NULL; 
    FILE *file = NULL; 
    char *plaintext  = NULL; 
    int len = 0; 
    int ret = 0; 
 
    file = fopen(path.c_str(), "r"); 
    if (file == NULL) { 
        return std::string(); 
    }
 
    //*注解4
    rsa = PEM_read_RSAPrivateKey(file, NULL, NULL, NULL); 
    if (rsa == NULL) {
        ERR_print_errors_fp(stdout); 
        fclose(file); 
        return std::string(); 
    } 
 
    len = RSA_size(rsa); 
    plaintext  = (char *)malloc(len + 1); 
    if (ciphertext == NULL) { 
        RSA_free(rsa); 
        fclose(file); 
        return std::string(); 
    }
    memset(ciphertext, 0, len + 1); 
    
    //*注解5
    ret = RSA_private_decrypt(str.length(), (unsigned char *)str.c_str(), (unsigned char*)plaintext, rsa, RSA_PKCS1_PADDING); 
    if (ret < 0) { 
        ERR_print_errors_fp(stdout);        free(plaintext); 
        RSA_free(rsa); 
        fclose(file); 
        return std::string(); 
    } 
    std::string s(plaintext, ret); 
 
    free(plaintext); 
    RSA_free(rsa); 
    fclose(file); 
    return s; 
} 

int main() { 
    std::string text = "357556062717012 / 09"; 
    std::string path = "rsa_public_key.pem"; 
    std::string encry = RsaEncrypt(text, path); 
    std::string encode = util::base64_encode((const unsigned char*)encry.c_str(), encry.size()); 
    std::cout << encode << std::endl; 
 
    //std::string s1 = "5K4oD28VpB0H1M/c7PuGeCBqQHXBMZxFWXR8IQL4Kp99rRoHblnIPPg2lIaDkBHi3jSBuMAy+VKU/raznuq338v3WyuDK1fJw/iQx171g1O1xHtGTOfcB8UaqLrxrqRridpuEf9l+diy1dMY8Wq1hdeSGuotb9nh9xSwDwcYMWQ="; 
    std::string s2 = "bh5QCzUXZ0JEZQ1lwnnib8MoDIX6ZLPzbZqMqL1538K/HZFD78sulpI+RsqKrt1xjOocgX2Y1d6GccGyFhRV8vyDKq/gPHNMYbpRYsu0DX+Ul8JzbrVw7UY/eNaeN0yVRhV+vYSbAeWsW/GJA6yyVYLki+BjRTj0d46AC4p9jhk="; 
    std::string path2 = "rsa_private_key.pem"; 
    std::string decry = RsaDecrypt(util::base64_decode(s2), path2); 
    //std::string decry = RsaDecrypt(encry, path2); 
    std::cout << decry << std::endl; 
 
    return 0; 
}